#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
IP地址处理工具函数
用于用户身份识别和IP地址标准化处理
"""

import hashlib
import ipaddress
from flask import request, current_app
from typing import Optional, Tuple


def get_client_ip() -> str:
    """
    获取客户端真实IP地址
    
    优先级：
    1. X-Forwarded-For (代理/负载均衡)
    2. X-Real-IP (Nginx代理)
    3. request.remote_addr (直连)
    
    Returns:
        str: 标准化的IP地址
    """
    # 尝试从X-Forwarded-For获取（支持代理链）
    forwarded_for = request.headers.get('X-Forwarded-For')
    if forwarded_for:
        # X-Forwarded-For可能包含多个IP，取第一个（原始客户端IP）
        client_ip = forwarded_for.split(',')[0].strip()
        if _is_valid_ip(client_ip):
            current_app.logger.debug(f"从X-Forwarded-For获取IP: {client_ip}")
            return _normalize_ip(client_ip)
    
    # 尝试从X-Real-IP获取
    real_ip = request.headers.get('X-Real-IP')
    if real_ip and _is_valid_ip(real_ip):
        current_app.logger.debug(f"从X-Real-IP获取IP: {real_ip}")
        return _normalize_ip(real_ip)
    
    # 使用Flask的remote_addr
    remote_addr = request.remote_addr or '127.0.0.1'
    current_app.logger.debug(f"从remote_addr获取IP: {remote_addr}")
    return _normalize_ip(remote_addr)


def _is_valid_ip(ip_str: str) -> bool:
    """
    验证IP地址是否有效
    
    Args:
        ip_str: IP地址字符串
        
    Returns:
        bool: 是否为有效IP地址
    """
    try:
        ipaddress.ip_address(ip_str)
        return True
    except ValueError:
        return False


def _normalize_ip(ip_str: str) -> str:
    """
    标准化IP地址格式
    
    Args:
        ip_str: 原始IP地址字符串
        
    Returns:
        str: 标准化的IP地址
    """
    try:
        ip_obj = ipaddress.ip_address(ip_str)
        # IPv6地址压缩表示
        if isinstance(ip_obj, ipaddress.IPv6Address):
            return str(ip_obj.compressed)
        # IPv4地址保持原样
        return str(ip_obj)
    except ValueError:
        current_app.logger.warning(f"无效IP地址，使用原始值: {ip_str}")
        return ip_str


def generate_user_id_from_ip(ip_address: str) -> str:
    """
    基于IP地址生成用户标识符
    
    使用SHA256哈希算法，取前12位确保唯一性和可读性
    格式：ip_[12位哈希值]
    
    Args:
        ip_address: 标准化的IP地址
        
    Returns:
        str: 用户标识符，格式为 ip_xxxxxxxxxxxx
    """
    # 使用SHA256哈希
    hash_obj = hashlib.sha256(ip_address.encode('utf-8'))
    hash_hex = hash_obj.hexdigest()
    
    # 取前12位作为用户标识
    user_id = f"ip_{hash_hex[:12]}"
    
    current_app.logger.debug(f"IP {ip_address} 生成用户ID: {user_id}")
    return user_id


def get_user_identity() -> Tuple[str, str]:
    """
    获取当前请求的用户身份信息
    
    Returns:
        Tuple[str, str]: (user_id, user_ip) 用户标识符和原始IP地址
    """
    user_ip = get_client_ip()
    user_id = generate_user_id_from_ip(user_ip)
    
    current_app.logger.info(f"用户身份识别: ID={user_id}, IP={user_ip}")
    return user_id, user_ip


def is_private_ip(ip_address: str) -> bool:
    """
    判断是否为私有IP地址
    
    Args:
        ip_address: IP地址字符串
        
    Returns:
        bool: 是否为私有IP
    """
    try:
        ip_obj = ipaddress.ip_address(ip_address)
        return ip_obj.is_private
    except ValueError:
        return False


def get_ip_info(ip_address: str) -> dict:
    """
    获取IP地址的详细信息
    
    Args:
        ip_address: IP地址字符串
        
    Returns:
        dict: IP地址信息
    """
    try:
        ip_obj = ipaddress.ip_address(ip_address)
        return {
            'ip': str(ip_obj),
            'version': ip_obj.version,
            'is_private': ip_obj.is_private,
            'is_loopback': ip_obj.is_loopback,
            'is_multicast': ip_obj.is_multicast,
            'compressed': str(ip_obj.compressed) if hasattr(ip_obj, 'compressed') else str(ip_obj)
        }
    except ValueError:
        return {
            'ip': ip_address,
            'version': 'unknown',
            'is_private': False,
            'is_loopback': False,
            'is_multicast': False,
            'compressed': ip_address,
            'error': 'Invalid IP address'
        }
